fix_xmlwriter_ascii_implicit_cellarray_segfault.patch: write the cell types
authorAnton Gladky <gladk@debian.org>
Tue, 28 Jul 2026 14:19:04 +0000 (16:19 +0200)
committerAnton Gladky <gladk@debian.org>
Tue, 28 Jul 2026 14:19:04 +0000 (16:19 +0200)
Guarding the null iterator only removed the crash, the array was still
written empty. Write arrays without an iterator through an explicit copy
and let the autopkgtest read the file back to check the cell count.

debian/patches/fix_xmlwriter_ascii_implicit_cellarray_segfault.patch
debian/tests/writeVTUAsciiImplicitCellTypes

index 7f303b40a1a88033900be02c41ab9ddc9e3737f8..4bb31ee48bb53dbeab5ba3b4cc1b3e2ee59971f6 100644 (file)
@@ -1,7 +1,12 @@
 Description: Fix segfault writing ascii .vtu files with implicit cell type arrays
  NewIterator() returns nullptr for the implicit cell-type arrays used
- since VTK 9.6. WriteAsciiData() dereferenced that nullptr via an
- unconditional iter->Delete(). Guard it. Closes yade FTBFS.
+ since VTK 9.6, so WriteAsciiData() dereferenced that nullptr in
+ iter->Delete(). Merely guarding the Delete() is not enough: the
+ templated writer already returns early on a null iterator, so the array
+ is then written empty, and since WriteInlineData() discards the return
+ value the writer reports success for a file which has lost all of its
+ cells. Write such arrays through an explicit copy instead.
+ Closes yade FTBFS.
 Forwarded: not-yet
 Author: Anton Gladky <gladk@debian.org>
 
@@ -9,7 +14,31 @@ Index: vtk9/IO/XML/vtkXMLWriter.cxx
 ===================================================================
 --- vtk9.orig/IO/XML/vtkXMLWriter.cxx
 +++ vtk9/IO/XML/vtkXMLWriter.cxx
-@@ -1978,7 +1978,10 @@ int vtkXMLWriter::WriteAsciiData(vtkAbs
+@@ -34,6 +34,7 @@
+ #include "vtkOutputStream.h"
+ #include "vtkPointData.h"
+ #include "vtkPoints.h"
++#include "vtkSmartPointer.h"
+ #include "vtkStdString.h"
+ #include "vtkStreamingDemandDrivenPipeline.h"
+ #include "vtkStringFormatter.h"
+@@ -1968,6 +1969,15 @@ int vtkXMLWriteAsciiData(ostream& os, it
+ int vtkXMLWriter::WriteAsciiData(vtkAbstractArray* a, vtkIndent indent)
+ {
+   vtkArrayIterator* iter = a->NewIterator();
++  vtkSmartPointer<vtkAbstractArray> copy;
++  if (!iter)
++  {
++    // Arrays which provide no iterator, such as the implicit arrays used since VTK 9.6
++    // for uniform cell types, are written through an explicit copy.
++    copy.TakeReference(vtkAbstractArray::CreateArray(a->GetDataType()));
++    copy->DeepCopy(a);
++    iter = copy->NewIterator();
++  }
+   ostream& os = *(this->Stream);
+   int ret;
+   switch (a->GetDataType())
+@@ -1978,7 +1988,10 @@ int vtkXMLWriter::WriteAsciiData(vtkAbst
        ret = 0;
        break;
    }
index 3070953f71d3a9426089339e10026fcb4476e615..8a4ac962977147bbc34b0ef4aa7a6427087e5c0e 100755 (executable)
@@ -30,8 +30,11 @@ cat <<EOF > demo.cpp
 #include <vtkNew.h>
 #include <vtkPoints.h>
 #include <vtkUnstructuredGrid.h>
+#include <vtkXMLUnstructuredGridReader.h>
 #include <vtkXMLUnstructuredGridWriter.h>
 
+#include <iostream>
+
 int main()
 {
   vtkNew<vtkPoints> points;
@@ -56,6 +59,18 @@ int main()
   writer->SetDataModeToAscii();
   writer->Write();
 
+  // the cell types have to be written, not only not to crash: an empty types
+  // array makes the reader silently drop every cell of the file
+  vtkNew<vtkXMLUnstructuredGridReader> reader;
+  reader->SetFileName("a.vtu");
+  reader->Update();
+  const vtkIdType cellCount = reader->GetOutput()->GetNumberOfCells();
+  if (cellCount != 3)
+  {
+    std::cerr << "read back " << cellCount << " cells instead of 3\n";
+    return EXIT_FAILURE;
+  }
+
   return EXIT_SUCCESS;
 }
 EOF